# Authors: M.Ravi (st111222)
#          Orathai Dumrongsukniwat (st111002)     
#
# Date: 5 September, 2010
#
#    The main controller for exercises in PS1 and PS2

include ERB::Util

require 'rubygems'
require 'hpricot'
require 'net/http'

class BasicsController < ApplicationController
  
  def index
    begin
    rescue => err
      puts "Exception: #{err}"
      #err
    end
  end
  
  
  # Problem Set 1
  # Action for 
  #   1. Displaying the main index page of PS1  
  
  def indexPS1
    
  end
  
  # Problem Set 1
  # Action for 
  #   1. Displaying Current Time
  #   2. Generate Error Log
  #   3. Show email addresses of the members
  def my_first_program
    @ps = Array.new
    @ps[0] = 1
    @ps[1] = 'Problem Set 1'
    @ps[2] = 'indexPS1'
    
    @value = ""
    @current_time = Time.now.strftime("%H:%M:%S")
    @program_name = "my-first-program"
    begin
      RAILS_DEFAULT_LOGGER.error("")
      message = 'About to divide by zero ' + Time.now.to_s 
      RAILS_DEFAULT_LOGGER.error(message)
      val = 1/0
    rescue Exception => err
      @value = "A divide by zero occured"
      RAILS_DEFAULT_LOGGER.error(err)
      RAILS_DEFAULT_LOGGER.error("")
      p message 
    end
  end
  
  # Problem Set 1
  # Action functionality 
  #   1. Shows the input box to get user's input for searching the emails
  
  def user_email_finder
    @ps = Array.new
    @ps[0] = 1 
    @ps[1] = 'Problem Set 1'
    @ps[2] = 'indexPS1'
    
    @program_name = "user-email-finder"
    if params[:q] && params[:q]!=nil 
      user_email_finder_results 
    end
  end
  
  # Problem Set 1
  # Action  
  #   1. Shows the input box 
  #   2. Takes the user's input, scraps the data from the source and finds the desired input from the scrapped html
  #   3. Render the output
  
  def user_email_finder_results
    @ps = Array.new
    @ps[0] = 1
    @ps[1] = 'Problem Set 1'
    @ps[2] = 'indexPS1'
    @program_name = "user-email-finder"
    begin
      require 'net/http'
      require 'open-uri'
      
      if params[:q]!=nil 
        findWhat = params[:q]
        @fw = findWhat			 
        host = "www.asdu.ait.ac.th"
        port = 80
        
        # Set cookie and reference path
        # http://www.asdu.ait.ac.th/PloneAPI/AdvSearch/assets/PDirectory/PDSearch.cfm
        get_cookie_path = '/PloneAPI/AdvSearch/assets/PDirectory/PDSearch.cfm'
        referer_path = 'http://www.asdu.ait.ac.th/ploneapi/AdvSearch/ploneadvsearch.html' 
        
        if @fw == nil
          # Case don't input data in search field : Show index page.
          index
        else
          # Case input data in search field : Sent name as parameter. 
          data = 'SName=' + @fw
        end
        
        post_path = '/PloneAPI/AdvSearch/assets/PDirectory/PDSearch.cfm'
        
        # Create new Net::HTTP object for www.asdu.ait.ac.th:80
        # and turn off SSL.
        http = Net::HTTP.new(host, port)
        http.use_ssl = false
        path = '/ploneapi/AdvSearch/ploneadvsearch.html'
        
        # Create new Net::HTTP object and open TCP connection and HTTP session
        url = URI.parse('http://www.asdu.ait.ac.th')
        res = Net::HTTP.start(url.host, url.port) {|http|
          http.get(get_cookie_path)
        }
        cookie = res.response['set-cookie']
        headers = {
						'Cookie' => cookie,
					'Referer' => referer_path ,
						'Content-Type' => 'application/x-www-form-urlencoded'
        }
        
        # Returns a pair of objects, a Net::HTTPResponse object and an entity body string
        resp, data = http.post(post_path , data, headers)
        
        @students = Array.new
        @staff = Array.new
        @student_exists = false
        @staff_exists = false
        
        # Check is found in student data?
        if data.index("</TABLE>")!=nil 	
          table1 = data[0, data.index("</TABLE>") + 8]
          data = data[data.index("</TABLE>") + 8, data.length]
          @student_exists = true
        end
        
        # Check is found in staff data?
        if data.index("</TABLE>")!=nil 	
          table2 = data[0, data.index("</TABLE>") + 8]
          @staff_exists = true
        end
        
        # Case found student data.
        if @student_exists
          table1 = table1.gsub("\t", "")
          table1 = table1.gsub("\n", "")
          table1 = table1.gsub("\r", "")
          
          table1 = table1[table1.index("<TR bgcolor=\"#EDF5FF\""),table1.length]
          scount = 0
          while table1.index("<TR bgcolor=\"#EDF5FF\">")
            row = table1[table1.index("<TR bgcolor=\"#EDF5FF\">") + 21, table1.index("</TR>")]
            row = row.gsub("\\", "")
            row = row.gsub("\"", "")
            # Keep last name.
            lname = row[row.index("<td class=body_01>")+18, row.index("</td>")]
            lname = lname[0, lname.index("</td>")]
            
            # Keep first name.
            row = row[row.index("</td>")+5, row.length]
            fname = row[row.index("<td class=body_01>")+18, row.index("</td>")]
            fname = fname[0, fname.index("</td>")]
            
            # Keep email address.
            row = row[row.index("mailto:")+7, row.length]
            email = row[0, row.index(" ")]
            
            # Keep first name, last name and email address into array.
            @students[scount] = [fname, lname, email]
            
            scount = scount+1
            table1 = table1[table1.index("</TR>") + 5,table1.length]
          end
        end
        
        # Case found in staff data.
        if @staff_exists
          table2 = table2.gsub("\t", "")
          table2 = table2.gsub("\n", "")
          table2 = table2.gsub("\r", "")
          
          table2 = table2[table2.index("<TR bgcolor=\"#EDF5FF\""),table2.length]
          scount = 0
          while table2.index("<TR bgcolor=\"#EDF5FF\">")
            row = table2[table2.index("<TR bgcolor=\"#EDF5FF\">") + 21, table2.index("</TR>")]
            row = row.gsub("\\", "")
            row = row.gsub("\"", "")
            
            # Keep last name.
            lname = row[row.index("<td class=body_01>")+18, row.index("</td>")]
            lname = lname[0, lname.index("</td>")]
            
            #remove unwanted html tags
            lname = lname.gsub(/<\/?[^>]*>/,"")
            
            # Keep first name.
            row = row[row.index("</td>")+5, row.length]
            fname = row[row.index("<td class=body_01>")+18, row.index("</td>")]
            fname = fname[0, fname.index("</td>")]
            
            #remove unwanted html tags
            fname = fname.gsub(/<\/?[^>]*>/,"")
            
            # Keep email address.
            if row.index("mailto") != nil
              row = row[row.index("mailto:")+7, row.length]
              email = row[0, row.index(" ")]
            end
            
            # Keep first name, last name and email address into array.
            @staff[scount] = [fname, lname, email]
            
            scount = scount+1
            table2 = table2[table2.index("</TR>") + 5,table2.length]
          end
        end
      else
        #no POST params found, so redirect to index
        redirect_to :action => :user_email_finder
      end
      
    rescue => err
      puts "Exception: #{err}"
      err
    end
  end
  
  # Problem Set 1, Problem Set 2
  # Action  
  #   1. Reads the input for the selected file
  #   2. Reads the file and renders the source content to the browser
  
  def our_view_source
    @file_contents_controller = ""
    @enable_view_source = true
    program_name = params[:pname]
    if @enable_view_source 
      @file_contents_controller = readFile('/var/www/web8/basics/app/controllers/basics_controller.rb')
    end
    # Read source files : controller and view file
    case program_name
      when "my-first-program"
      # the function h escapes the html tags in the files
      @file_contents_view = Array.new()
      @file_contents_view[0] = "my_first_program.html.erb"
      @file_contents_view[1] = h readFile('/var/www/web8/basics/app/views/basics/my_first_program.html.erb')
    
      when "user-email-finder"
      @file_contents_view = Array.new()
      @file_contents_view[0] = "user_email_finder.html.erb"
      @file_contents_view[1] = h readFile('/var/www/web8/basics/app/views/basics/user_email_finder.html.erb')
      
      @file_contents_view1 = Array.new()
      @file_contents_view1[0] = "user_email_finder_results.html.erb"
      @file_contents_view1[1] = h readFile('/var/www/web8/basics/app/views/basics/user_email_finder_results.html.erb')
    
      when "quotations"
      @file_contents_view = Array.new()
      @file_contents_view[0] = "our_quotations.html.erb"
      @file_contents_view[1] = h readFile('/var/www/web8/basics/app/views/basics/our_quotations.html.erb')
      
      @file_contents_view1 = Array.new()
      @file_contents_view1[0] = "quotation_search_results.html.erb"
      @file_contents_view1[1] = h readFile('/var/www/web8/basics/app/views/basics/quotation_search_results.html.erb')
      
      when "quotationSearchResults"
      @file_contents_view = Array.new()
      @file_contents_view[0] = "our_quotations.html.erb"
      @file_contents_view[1] = h readFile('/var/www/web8/basics/app/views/basics/our_quotations.html.erb')
      
      @file_contents_view1 = Array.new()
      @file_contents_view1[0] = "quotation_search_results.html.erb"
      @file_contents_view1[1] = h readFile('/var/www/web8/basics/app/views/basics/quotation_search_results.html.erb')

      when "site"
      @file_contents_view = Array.new()
      @file_contents_view[0] = "our_quotations.html.erb"
      @file_contents_view[1] = h readFile('/var/www/web8/basics/app/views/basics/our_quotations.html.erb')

      @file_contents_view1 = Array.new()
      @file_contents_view1[0] = "quotation_search_results.html.erb"
      @file_contents_view1[1] = h readFile('/var/www/web8/basics/app/views/basics/quotation_search_results.html.erb')
    else
      #We don't have a valid file param for which the source is to be rendered, So redirect to basics/
      redirect_to "http://web8.cs.ait.ac.th/basics/"		
    end
  end
  
  # Problem Set 1
  # Action  
  #   1. Shows the last 25 lines of the production log to the user 
  
  def view_error_log
    @ps = Array.new
    @ps[0] = 1 
    @ps[1] = "Problem Set 1"
    @ps[2] = "indexPS1"	
    
    @program_name = ""
    @logs = %x[tail -n 25 log/production.log]
  end
  
  # Problem Set 1
  # Action  
  #   1. This action is used internally by the action view_source to read the contents of a given file
  #      Input - the filename (String) 
  #      Output - the contents of the filename (String) 
  
  #private
  
  def readFile(fileName)
    # Read File with Exception Handling
    counter = 1
    contents = ""
    
    begin
      # Create new read-only file
      file = File.new(fileName, "r")
      while (line = file.gets)
        contents = contents.concat(line)
      end
      file.close
      
    rescue => err
      puts "Exception: #{err}"
      err
    end
    return contents
  end
  
  # Problem Set 1, Problem Set 2
  # Action  
  #   1. Displays the references layout
  
  def references
    @ps = Array.new
    @ps[0] = 0 
    render :file => 'layouts/references' 
  end
  
  # Problem Problem Set 2
  # Action  
  #   1. Takes the user input for searching, reordering the quotations
  #   2. Invokes the view that has inputs for searching, reordering, importing xml, creating a new quotation    
  
  def our_quotations
    @ps = Array.new 	 
    @ps[0] =2 
    @ps[1] = ""
    @ps[2] = ""	
    
    @program_name = "quotations"
    
    if params[:quotation]
      if params[:optCat] == "old"
        params[:quotation][:category] = params[:selCat]
      end
      
      @quotation = Quotation.new( params[:quotation] )
      if @quotation.save
        flash[:notice] = 'Quotation was successfully created.'
        @quotation = Quotation.new
      else
        flash[:notice] = 'Couldn\'t save quotation'
      end
    else
      @quotation = Quotation.new
    end
    
    if params[:sort_by] == "date"
      @oby = params[:sort_by]
      if cookies[:exclude]
        @quotations = Quotation.find( :all,:conditions => "id NOT IN (" +  cookies[:exclude] + ")", :order => :created_at )
      else
        @quotations = Quotation.find( :all, :order => :created_at )
      end
    else
      @oby = "category" 
      if cookies[:exclude]
        @quotations = Quotation.find( :all, :conditions => "id NOT IN (" + cookies[:exclude] + ")", :order => :category )
      else
        @quotations = Quotation.find( :all, :order => :category )
      end
    end
    
    # Get DISTINCT category from table 'Quotation' for drop down list.
    @categories = Quotation.find( :all, :select => 'DISTINCT category', :order => :category )
  end
  
  # Problem Problem Set 2
  # Action  
  #   1. Takes the user input for searching, reordering the quotations
  #   2. Invokes the view that has inputs for searching, reordering, importing xml, creating a new quotation    
  def quotation_search_results
    @ps = Array.new
    @ps[0] = 2
    @ps[1] = "Quotations"
    @ps[2] = "quotations"	
    @program_name = "quotationSearchResults"
    if params[:q]
      @fw = params[:q]
      if cookies[:exclude]
        @quotations = Quotation.find( :all, :conditions => ["(UPPER(author_name) like ? OR UPPER(quote) like ?) AND id NOT IN (" + cookies[:exclude]  + ")", "%" + @fw.upcase + "%", "%" + @fw.upcase + "%" ])
        p cookies[:exclude]
        p @quotations
      else
        @quotations = Quotation.find( :all, :conditions => ["UPPER(author_name) like ? OR UPPER(quote) like ?", "%" + @fw.upcase + "%", "%" + @fw.upcase + "%"])   
        p "no cookies"
      end
      
      if @quotations.empty?
        @quotation_exists = false
      else
        @quotation_exists = true 
      end
    end
  end
  
  
  # Problem Problem Set 2
  # Action  
  #   1. Takes the author name and the quotation the user selects, and deletes the modifies the cookie with the quotation id removed
  
  def killCookie
    # for un-escaping the get parameters
    require 'cgi'
    if params[:author_name]	&& params[:quote]
      @quotation = Quotation.find(:first, :conditions => ['author_name = ? and quote=?', CGI.unescape(params[:author_name]), CGI.unescape(params[:quote])])
      #p @quotation 
      #if @quotation.length == 0
      #else
      if cookies[:exclude]
        cookies[:exclude]= cookies[:exclude] + "," + @quotation.id.to_s()
      else
        cookies[:exclude]= "" + @quotation.id.to_s()
      end
      #end
      
      redirect_to :action => :quotations, :sort_by => params[:sort_by]
    end
  end
  
  # Problem Problem Set 2
  # Action  
  #   1. Deletes the cookie entirely, so that personalization is cleared 
  def eraseMyPersonalization
    cookies.delete :exclude
    redirect_to :action => :quotations
  end
  
  # Problem Problem Set 2
  # Action  
  #   1. Extracts the elements of an XML file and saves each quotation into database if its not present in the database already. 
  #   Note: This action is not in use, We have an alternative method using Hpricot doing this
  #private
  
  def importXml
    if false
      require 'net/http'
      require 'rexml/document'
      
      url = 'http://web8.cs.ait.ac.th/basics/quotations-xml'
      
      # get the XML data as a string
      xml_data = Net::HTTP.get_response(URI.parse(url)).body
      
      # extract event information
      doc = REXML::Document.new(xml_data)
      quotation_ids = []
      insertion_dates = []
      author_names = []
      categories = []
      quotes = []
      
      doc.elements.each('quotations/onequote/quotation_id') do |ele|
        quotation_ids << ele.text
      end
      
      doc.elements.each('quotations/onequote/insertion_date') do |ele|
        insertion_dates << ele.text
      end
      
      doc.elements.each('quotations/onequote/author_name') do |ele|
        author_names << ele.text
      end
      
      doc.elements.each('quotations/onequote/category') do |ele|
        categories << ele.text
      end
      
      doc.elements.each('quotations/onequote/quote') do |ele|
        quotes << ele.text
      end
      
      
      # print all events
      quotation_ids.each_with_index do |quotation_id, idx|
        q = Quotation.find_by_sql("select * from quotations where author_name = '" + author_names[idx] + "' AND quote = '" + quotes[idx] + "'" )
        
        if q.empty?
          quo = Quotation.create(:author_name => author_names[idx], :quote => quotes[idx], :category => categories[idx], :insertion_date => insertion_dates[idx])
          quo.save()
          
        end
        print "#{quotation_id} => #{insertion_dates[idx]} => #{author_names[idx]} => #{categories[idx]}\n"
      end
      
      @quotations = Quotation.find(:all)
    end	
  end
  
  # Problem Problem Set 2
  # Action  
  #   1. Queries the database for all possible quotations and invokes the view to render the xml 
  
  def quotations_xml
    @ps = Array.new
    @ps[0] =2 
    @ps[1] = "Problem Set 2"
    @ps[2] = "indexPS2"	
    
    # Get all data from table 'Quotation'.
    @quotations = Quotation.find(:all, :order => :id)
  end
  
  # Problem Problem Set 2
  # Action  
  #   1. Reads the user selected option for the web server to import the xml from and then imports the quotations from the xml to the database if they don't exist in the 
  #      quotations table
  #   2.   Eg. for the url http://web7.cs.ait.ac.th/basics/quotations_xml
  def import_xml
    @ps = Array.new 	 
    @ps[0] =2 
    @ps[1] = "Problem Set 2"
    @ps[2] = "indexPS2"	
    if params[:selWeb] != "None"
      # Send request and get response from URL such as 'http://web7.cs.ait.ac.th/basics/quotations_xml'
      res = Net::HTTP.get(URI( params[:selWeb] ))
      doc = Hpricot(res)
      
      Quotation.transaction do
        # Search tag by Hpricot and loop read data in each tag
         (doc/'onequote').each do |onequote_element|
          @author = (onequote_element/'author_name').inner_html
          @catogery = (onequote_element/'category').inner_html
          @quote = (onequote_element/'quote').inner_html
          
          # Check author name and quote from another web server
          #   If (author name and quote) exist in database, do nothing
          #   Otherwise, INSERT data into table 'Quotation'.
          # After updated, refresh web page. 
          if !(Quotation.find_by_author_name(@author) and Quotation.find_by_quote(@quote))
            @quotation = Quotation.new
            @quotation.author_name = @author
            @quotation.category = @catogery
            @quotation.quote = @quote
            @quotation.save
          end
        end
      end
    end
    redirect_to(:action => 'quotations' )
  end
  
  def showDBExercises
    @file_contents = readFile('/var/www/web8/basics/ps2.sql')
  end
  
  def showDBDump
    @file_contents = readFile('/var/www/web8/db_dump/pgdump.txt')
  end
  
  def showProfile
    @name = params[:name]	
    case @name
      when "userprofile1"
      render :file => 'layouts/userprofile1' 
      when "userprofile2"
      render :file => 'layouts/userprofile2' 
      when "userprofile3"
      render :file => 'layouts/userprofile3' 
    end	
  end
  
  def documentation
  end
end
